package com.itheima.day14.threadStatus.test1;

//目的 : 本案例主要演示WAITING的状态转换。
//        需求 ：编写一段代码，依次显示一个线程的这些状态：NEW -> RUNNABLE -> WAITING -> RUNNABLE ->
//        TERMINATED
public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        // 定义一个对象，用来加锁和解锁
        Object obj = new Object();

        // 定义一个内部线程
        Thread t = new Thread(() -> {
            System.out.println("2.执行t.start()之后，线程的状态：" + Thread.currentThread().getState());
            synchronized (obj) {
                try {
                    // t需要休眠100毫秒
                    Thread.sleep(100);

                    // t线程100毫秒之后，通过wait()方法释放obj对象是锁
                    obj.wait();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("4.被object.notify()方法唤醒之后，线程的状态：" + Thread.currentThread().getState());
        });

        // 获得start()之前的状态
        System.out.println("1.通过new初始化一个线程，但是还没有start()之前，线程的状态：" + t.getState());

        // 启动线程
        t.start();

        // main线程休眠150毫秒
        Thread.sleep(150);

        // 因为t在第100毫秒进入wait等待状态，所以第150毫秒肯定可以获取其状态
        System.out.println("3.执行object.wait()，线程的状态：" + t.getState());

        // 声明另一个线程进行解锁
        new Thread(() -> {
            synchronized (obj){
                // 唤醒等待的线程
                obj.notify();
            }

        }).start();

        // main线程休眠10毫秒等待t线程能够苏醒
        Thread.sleep(10);

        // 获取t运行结束之后的状态
        System.out.println("5.线程执行完毕之后，线程的状态：" + t.getState() + "\n");
    }

    // 打印结果：
//      1.通过new初始化一个线程，但是还没有start()之前，线程的状态：NEW
//      2.执行t.start()之后，线程的状态：RUNNABLE
//      3.执行object.wait()，线程的状态：WAITING
//      4.被object.notify()方法唤醒之后，线程的状态：RUNNABLE
//      5.线程执行完毕之后，线程的状态：TERMINATED
}
